package com.mccken.practice;

import java.util.concurrent.TimeUnit;
import java.util.concurrent.locks.AbstractQueuedSynchronizer;
import java.util.concurrent.locks.Condition;
import java.util.concurrent.locks.Lock;

/**
 * @program: mccken-collect
 * @description:
 * @author: mccken
 * @create: 2023-12-11 18:02
 **/
public class MyLock04 implements Lock {

	@Override
	public void lock() {
		sync.acquire(1);
	}

	@Override
	public void lockInterruptibly() throws InterruptedException {

	}

	@Override
	public boolean tryLock() {
		return false;
	}

	@Override
	public boolean tryLock(long time, TimeUnit unit) throws InterruptedException {
		return false;
	}

	@Override
	public void unlock() {
		sync.release(0);
	}

	@Override
	public Condition newCondition() {
		return null;
	}

	private static class Sync extends AbstractQueuedSynchronizer {
		
		public boolean tryRelease(int releases) {
			setExclusiveOwnerThread(null);
			setState(0);
			return true;
		}
	}
	
	// 公平独占同步器
	private static class FairSync extends MyLock04.Sync {
		
		public boolean tryAcquire(int acquires) {
			if (!hasQueuedPredecessors() && compareAndSetState(0, 1)) {
				return true;
			}
			return false;
		}
	}
	
	private static class NonfairSync extends MyLock04.Sync {
		
		public boolean tryAcquire(int acquires) {
			if (compareAndSetState(0, 1)) {
				return true;
			}
			return false;
		}
	}
	
	private Sync sync;
	
	private MyLock04(boolean fair) {
		sync = fair? new FairSync() : new NonfairSync();
	}
}
